import threading
from .zlgcan.zlgcan import ZLG_CONSTANT
from icecream import ic as ic_debugger
import time
import traceback
import sys


class Backend_msgReader():
    def __init__(self, zcanlib, chn_handle, global_recv_queues) -> None:
        self.ZCANLIB = zcanlib
        self.CHN_HANDLE = chn_handle
        self.GLOBAL_MSG_QUEUER = global_recv_queues

        self.can_readMsg_thread_init()
        pass

    def can_readMsg_thread_init(self):

        # # 设置event，event控制什么时候开启接收,这样就不用一直在接收报文，浪费资源
        self.readMsg_event = threading.Event()
        self.can_readMsg_thread_close()

        self.readMsg_thread = threading.Thread(
            None, target=self.backend_MsgReadThreadFunc, name="Backend_MsgRead_Thread")
        self.readMsg_thread.start()

        pass

    def can_readMsg_thread_open(self):
        self.readMsg_event.set()

    def can_readMsg_thread_close(self):
        self.readMsg_event.clear()

    def backend_MsgReadThreadFunc(self):
        MAX_RCV_NUM = 10
        kick_temp = 0
        DELTA = 0.005
        SHOW_PERIOD = 5

        can_num_show_period = 0
        canfd_num_show_period = 0

        try:
            # is_set不阻塞线程，适用于非阻塞场景
            # wait() 阻塞现场，可以重启
            while self.readMsg_event.wait():
                can_num = self.ZCANLIB.GetReceiveNum(
                    self.CHN_HANDLE, ZLG_CONSTANT.ZCAN_TYPE_CAN)
                canfd_num = self.ZCANLIB.GetReceiveNum(
                    self.CHN_HANDLE, ZLG_CONSTANT.ZCAN_TYPE_CANFD)

                # 没有1秒钟的时间，就打印一下can_num和canfd_num
                kick_temp += 1
                can_num_show_period += can_num
                canfd_num_show_period += canfd_num

                if kick_temp > SHOW_PERIOD / DELTA:
                    # print(f'[file:{__file__}]=>[line:{(sys._getframe().f_lineno)}]==>can_num_show_period:{
                    # can_num_show_period},canfd_num_show_period:{canfd_num_show_period}')
                    ic_debugger(can_num_show_period, canfd_num_show_period)
                    can_num_show_period = 0
                    canfd_num_show_period = 0
                    kick_temp = 0

                if not can_num and not canfd_num:
                    time.sleep(DELTA)  # wait 5ms
                    # time.sleep(0.5)
                    continue

                if can_num:
                    while can_num and self.readMsg_event.wait():
                        # ic_debugger(can_num)
                        read_cnt = MAX_RCV_NUM if can_num >= MAX_RCV_NUM else can_num
                        can_msgs, act_num = self.ZCANLIB.Receive(
                            self.CHN_HANDLE, read_cnt, MAX_RCV_NUM)
                        if act_num:
                            # [ ]处理msg
                            for i in range(act_num):
                                # cur_msg = can_msgs[i].frame
                                cur_msg = can_msgs[i]
                                # ic_debugger(cur_msg)
                                self.GLOBAL_MSG_QUEUER.append_msg_to_queues(
                                    cur_msg, isCanFD=False)

                                pass
                        else:
                            break
                        can_num -= act_num
                if canfd_num:
                    while canfd_num and self.readMsg_event.wait():
                        read_cnt = MAX_RCV_NUM if canfd_num >= MAX_RCV_NUM else canfd_num
                        canfd_msgs, act_num = self.ZCANLIB.ReceiveFD(
                            self.CHN_HANDLE, read_cnt, MAX_RCV_NUM)
                        if act_num:
                            # [ ] 处理 canfd msg
                            # ic_debugger(canfd_msgs[i].frame)
                            for i in range(act_num):
                                # cur_msg_fd = canfd_msgs[i].frame
                                cur_msg_fd = canfd_msgs[i]
                                # if 1:
                                #     msg_type = (
                                #         self.CANFDMsg2View_std(cur_msg_fd))
                                #     print(f'[file:{__file__}]=>[line:{(sys._getframe().f_lineno)}]==>{
                                #         msg_type.id_str}::{msg_type.data_str}')
                                self.GLOBAL_MSG_QUEUER.append_msg_to_queues(
                                    cur_msg_fd, isCanFD=True)

                        else:
                            break
                        canfd_num -= act_num
        except:

            print(f'[file:{__file__}]=>[line:{(sys._getframe().f_lineno)}]==>{
                  traceback.format_exc()}')
